let machine = require('../public/index.js');
const dao = require('./dao');
const cakeModel = new dao();
let dbDao = new dao();
const date = require('silly-datetime');
const { order } = require('../db/schema');
const config = require('../config/index.js');
class cake extends machine {
    constructor(httpClient, tcpServe) {
        // 窗口topic参数输入：this.topics = [{内窗口},{外窗口},]
        super(httpClient, tcpServe, config.machineTopic());
        this.toOrder = true;
        this.storeId = '1176112658763165697';
        this.date = date.format(new Date(), 'YYYYMMDD');
        this.listenKafka();
        this.cakeConnect();
        this.workingMeadId = [];    //保存当前工作取饮料订单ID[正在制作id,窗口1ID，窗口2ID]
        this.topics = config.machineTopic();
        // 连接表情屏
        tcpServe.clientConnected(config.faceIp());
        // this.test();

    }
    test() {
        let params = { status: 3 }
        cakeModel.findAllOrder(params, (res) => {
            // 判断是否有制餐完成的订单
            if (res) {
                console.log(res)
                // let detail = JSON.parse(res.orderDetail);
                for (let item in res) {
                    console.log('item', res[item]);
                    if (res[item]._mealId == 2) {
                        console.log("打开窗门");
                    }
                }
            }
        });
    }
    receive(key, arr, type, randomNumber) {
        this.clients[key].deviceType = arr[0];
        this.clients[key].timestamp = (new Date()).getTime();
        let res = {
            content: '',
            isSend: true
        };
        if (arr[0] === 170) {
            // 蛋糕机的头信息是AA，170对应的是蛋糕机设备
            switch (type) {
                case 0:
                    console.log("接收心跳");
                    this.updateStatus(arr, key);
                    this.getFreeOrder(key);
                    res.content = this.messageResponse(0);
                    break;
                case 3:
                    console.log("接收状态上报");
                    this.updateStatus(arr, key);
                    let isError = false, // 是否异常
                        code = '', //设备状态
                        message = ''; // 异常信息
                    // http 及时上报该设备状态
                    if (this.clients[key].deviceStatus === 2) {
                        isError = true;
                        code = 'cake';
                        message = '设备异常'
                    }
                    if (isError) {
                        this.postAbnormal({ storeId: this.storeId, code: code, message: message }, (res) => {
                            console.log(res);
                        });
                    } else {
                        this.getFreeOrder(key);
                    }
                    res.content = this.messageResponse(0);
                    break;
                case 4:
                    console.log("下单成功");
                    this.tcpServe.clientSend('c,4\r\n');
                    this.clients[key].workStatus = 2;
                    let params = { _mealId: arr[4], date: this.date }
                    cakeModel.findFreeOrder(params, (res) => {
                        let detail = JSON.parse(res.orderDetail);
                        this.postMealAbnormal({
                            storeId: this.storeId,
                            orderId: detail.orderId,
                            productId: detail.productId,
                            productStatus: '22',
                            orderDetailId: detail.id
                        }, (res) => {
                            console.log("上报云端", res)
                            cakeModel.updateOrder({ date: this.date, _mealId: arr[4] }, { status: '1' });
                        });
                    });
                    res.isSend = false;
                    break;
                case 5:
                    console.log("PLC接收到出餐命令");
                    res.isSend = false;
                    break;
                case 6:
                    console.log("制餐完成指令");
                    this.tcpServe.clientSend('c,5\r\n');
                    // 获取制作完成订单详情
                    param = { _mealId: arr[4], date: this.date }
                    cakeModel.findFreeOrder(param, (res) => {
                        let detail = JSON.parse(res.orderDetail);
                        this.postMealAbnormal({
                            storeId: this.storeId,
                            orderId: detail.orderId,
                            productId: detail.productId,
                            productStatus: '58',
                            orderDetailId: detail.id
                        }, (res) => {
                            cakeModel.updateOrder({ date: this.date, _mealId: arr[4] }, { status: '2' });
                        });
                    });
                    res.content = this.messageResponse(0);
                    break;
                case 7:
                    console.log("取餐完成指令");
                    this.tcpServe.clientSend('c,6\r\n');
                    // 获取取餐完成订单详情
                    param = { _mealId: arr[4], date: this.date }
                    cakeModel.findFreeOrder(param, (res) => {
                        let detail = JSON.parse(res.orderDetail);
                        this.postMealAbnormal({
                            storeId: this.storeId,
                            orderId: detail.orderId,
                            productId: detail.productId,
                            productStatus: '510',
                            orderDetailId: detail.id
                        }, (res) => {
                            cakeModel.updateOrder({ date: this.date, _mealId: arr[4] }, { status: '3' });
                        });
                    });
                    res.content = this.messageResponse(0);
                    break;
                case 8:
                    console.log("取餐超时反馈");
                    param = { _mealId: arr[4], date: this.date }
                    cakeModel.findFreeOrder(param, (res) => {
                        let detail = JSON.parse(res.orderDetail);
                        this.postMealAbnormal({
                            storeId: this.storeId,
                            orderId: detail.orderId,
                            productId: detail.productId,
                            productStatus: '58',
                            orderDetailId: detail.id
                        }, (res) => {
                            cakeModel.updateOrder({ date: this.date, _mealId: arr[4] }, { status: '6' });
                        });
                    });
                    res.content = this.messageResponse(0);
                    break;
                case 9:
                    console.log("PLC已强制开门");
                    res.isSend = false;
                    break;
                default:
                    res.content = '';

            }
            return res;

        } else if (arr[0] === 10) {
            // 饮料机
            switch (type) {
                case 0:
                    console.log("接收心跳");
                    this.getFreeOrder(key);
                    this.updateStatus(arr, key);
                    break;
                case 1:
                    console.log("接收制作状态");
                    //TODO 告诉云端该菜品制作情况,修改数据库该订单情况
                    if (arr[4] == 2) {
                        // 完成制作
                    } else if (arr[4] == 3) {
                        // 到达取餐口
                       
                        this.tcpServe.clientSend('c,5\r\n');
                        // 获取制作完成订单详情
                        param = { _mealId: this.workingMeadId[arr[7]], date: this.date }
                        cakeModel.findFreeOrder(param, (res) => {
                            let detail = JSON.parse(res.orderDetail);
                            this.postMealAbnormal({
                                storeId: this.storeId,
                                orderId: detail.orderId,
                                productId: detail.productId,
                                productStatus: '58',
                                orderDetailId: detail.id
                            }, (res) => {
                                cakeModel.updateOrder({ date: this.date, _mealId: this.workingMeadId[arr[7]] }, { status: '2' });
                            });
                        });
                    }
                    break;
                case 2:
                    console.log("客户端返回是否可以制餐");
                    if (arr[4] === 1) {
                        this.tcpServe.clientSend('c,4r\n');
                        // 修改设备状态为繁忙
                        this.clients[key].workStatus = 2;
                        // 修改数据库订单状态
                        param = { _mealId: this.workingMeadId[0], date: this.date }
                        cakeModel.findFreeOrder(params, (res) => {
                            let detail = JSON.parse(res.orderDetail);
                            this.postMealAbnormal({
                                storeId: this.storeId,
                                orderId: detail.orderId,
                                productId: detail.productId,
                                productStatus: '22',
                                orderDetailId: detail.id
                            }, (res) => {
                                console.log("上报云端", res)
                                cakeModel.updateOrder({ date: this.date, _mealId: this.workingMeadId[0] }, { status: '1' });
                            });
                        });
                    } else {
                        console.log('设备繁忙');
                    }
                    res.isSend = false;
                    break;
                case 3:
                    console.log("接收状态上报");
                    this.updateStatus(arr, key);
                    // TODO 上报云端设备状态
                    break;
                case 4:
                    console.log("强制开门信息回复:");
                    if (arr[4] === 1) {
                        console.log("可以开门");
                    }
                    res.isSend = false;
                    break;
                default:
                    res.content = '';

            }
            return res;
        }
    }
    cakeConnect() {
        this.tcpConnect((socket) => {
            // 1代表cake,2代表
            let key = socket.remoteAddress;//每个用户的唯一标示
            // 设备首次连接触发
            let times = (new Date()).getTime();
            // 取餐口1（里面）、2（外面）
            let intakeStatus = { '1': 1, '2': 1 }
            //初始化设备状态
            // timestamp:设备最新心跳时间戳,workStatus:工作状态,controlStatus:控制模式,deviceStatus:设备状态,intakeStatus:设备层状态
            this.clients[key] = { socket, timestamp: times, workStatus: 2, controlStatus: 1, deviceStatus: 1, intakeStatus: intakeStatus, deviceType: '' };
            this.clientConnected(socket);
            this.tcpTimeout(socket, 50, () => {
                console.log("超时时间到，设备下线");
                socket.destroy();        //主动踢客户端下线
            });
        });
    }

    /**
     * 扫码枪获取信息后方法
     *
     * @param {*} data 粘包后数据
     * @memberof machine
     */
    receiveScanData(data) {
        // 发送表情
        this.tcpServe.clientSend('c,1\r\n');
        // 查询全部制作完成的订单
        let params = { status: 2 }
        cakeModel.findAllOrder(params, (res) => {
            // 判断是否有制餐完成的订单
            let PLCTopic = config.machineTopic(), detail, intake, foodTye;
            if (res) {
                for (let index in res) {
                    detail = JSON.parse(res[index].orderDetail);
                    // 判断空闲订单是否与扫码订单一致
                    if (detail.orderId == data.orderId) {
                        // 判断该菜单topic是属于哪个设备和出餐窗口
                        for (let item in PLCTopic) {
                            if (PLCTopic[item].topic == res[index].topic) {
                                intake = item + 1;
                            }
                        }
                        // 判断是否蛋糕机  82：蛋糕机   70饮料机
                        foodTye = res[index].foodTye == 82 ? 0 : 1;
                        // 通过topic的位置获取对应设备的key
                        let key = config.PLCip()[foodTye];
                        let head = foodTye == 0 ? 170 : 10;
                        let type = foodTye == 0 ? 5 : 4;
                        content = this.messageResponse(head, type, this.getRandom(), 2, intake);
                        this.tcpSend(key, content);
                        break;
                    }

                }
                // this.getOrderDetail({orderId: data.orderId, deviceCode: 'cake'}, (response) => {
                //     console.log(response);
                //     if(response.statusCode === '200') {
                //         this.order = data.orderId;
                //         response.data.orderDetail

                //     }
                // })

            }
        });
    }


    /**
     * 从数据库获取空闲订单并向PLC 下发制单指令
     * @param {socket key} key 
     */
    sendMeal(key) {
        let type = this.clients[key].deviceType;
        let window1 = this.clients[key].intakeStatus['1'];
        let window2 = this.clients[key].intakeStatus['2'];
        let content, topics, params;
        if (type == 170) {
            // 判断哪个窗口空闲
            if (window1 + window2 == 2) {
                // 两个窗口都空闲,寻找这两窗口中最新的一条订单制作
                params = {
                    status: 0,
                    foodTye: 82,
                    $or: [{ topic: this.topics[0].topic }, { topic: this.topics[1].topic }],
                };
                order.findOne(params).sort('-_id').exec((err, res) => {
                    if (res) {
                        console.log('res', res);
                        this.date = res.date;
                        let meadId = res._mealId;
                        let intake = res.topic == this.topics[0].topic ? 1 : 2; //判断获取的窗口是否内外窗口
                        let detail = JSON.parse(res.orderDetail);
                        let productId = detail.productId;
                        let rows = this.toList(detail.rows, detail.columns, 4) //柜子默认是4列
                        console.log(detail.specInfo);
                        let specinfoList = this.toSpecinfo(detail.specInfo);
                        console.log('取餐口', intake);
                        content = this.messageResponse(170, 4, this.getRandom(), 16, meadId, productId, 1, rows, specinfoList[0], specinfoList[1], specinfoList[2], intake);
                        this.tcpSend(key, content);
                    }
                })

            } else if (window1 + window2 == 3) {
                // 其中有一个窗口空闲
                topics = window1 == 1 ? this.topics[0].topic : this.topics[1].topic;       //如果窗口1空闲则获取窗口1的订单topic
                params = { status: 0, topic: topics, foodTye: 82 };
                cakeModel.findFreeOrder(params, (res) => {
                    if (res) {
                        console.log('res', res);
                        this.date = res.date;
                        let intake = res.topic == this.topics[0].topic ? 1 : 2; //判断获取的窗口是否内外窗口
                        let detail = JSON.parse(res.orderDetail);
                        let meadId = res._mealId;
                        let productId = detail.productId;
                        let rows = this.toList(detail.rows, detail.columns, 4) //柜子默认是4列
                        let specinfoList = this.toSpecinfo(detail.specinfo);
                        content = this.messageResponse(170, 4, this.getRandom(), 16, meadId, productId, 1, rows, specinfoList[0], specinfoList[1], specinfoList[2], intake);
                        this.tcpSend(key, content);
                    }
                });
            }

        } else if (type == 10) {
            if (window1 + window2 == 2) {
                // 两个窗口都空闲,寻找这两窗口中最新的一条订单制作
                params = {
                    status: 0,
                    foodTye: 70,
                    $or: [{ topic: this.topics[0].topic }, { topic: this.topics[1].topic }],
                };
                order.findOne(params).sort('-_id').exec((err, res) => {
                    console.log('res', res);
                    this.date = res.date;
                    let intake = res.topic == this.topics[0].topic ? 1 : 2; //判断获取的窗口是否内外窗口
                    let detail = JSON.parse(res.orderDetail);
                    this.workingMeadId[0] = res._mealId;
                    this.workingMeadId[intake] = res._mealId;
                    let productId = detail.productId;
                    let specinfoList = this.toSpecinfo(detail.specinfo);
                    content = this.messageResponse(10, 2, this.getRandom(), 28, intake, productId, specinfoList[0], specinfoList[1], 0, 0, 0, 0, 0, 0, 0, 0, 0);
                    this.tcpSend(key, content);
                })

            } else if (window1 + window2 == 3) {
                // 其中有一个窗口空闲
                topics = window1 == 1 ? this.topics[0].topic : this.topics[1].topic;       //如果窗口1空闲则获取窗口1的订单topic
                params = { status: 0, topic: topics, foodTye: 70 };
                cakeModel.findFreeOrder(params, (res) => {
                    console.log('res', res);
                    this.date = res.date;
                    let intake = res.topic == this.topics[0].topic ? 1 : 2; //判断获取的窗口是否内外窗口
                    let detail = JSON.parse(res.orderDetail);
                    let meadId = res._mealId;
                    this.workingMeadId[0] = res._mealId;
                    this.workingMeadId[intake] = res._mealId;
                    let productId = detail.productId;
                    let specinfoList = this.toSpecinfo(detail.specinfo);  //规格
                    content = this.messageResponse(10, 2, this.getRandom(), 28, intake, productId, specinfoList[0], specinfoList[1], 0, 0, 0, 0, 0, 0, 0, 0, 0);
                    this.tcpSend(key, content);
                });
            }
        }


    }
    /**
    * 更新PCL状态信息
    * @param {Object} data  接收的信息
    * @param {Object} key   PLC识别KEY
    */
    updateStatus(data, key) {
        this.clients[key].controlStatus = data[4];
        this.clients[key].workStatus = data[5];
        this.clients[key].deviceStatus = data[6];
        this.clients[key].intakeStatus['1'] = data[7];
        this.clients[key].intakeStatus['1'] = data[8];

    }
    // 从数据库获取空闲订单
    getFreeOrder(key) {
        setTimeout(() => {
            if (this.clients[key].workStatus == '1' && this.clients[key].deviceStatus == '1') {
                this.sendMeal(key);
            }
        });
    }
    // 蛋糕机下发订单
    toOrderPLC(orderDetail) {
        this.sendMakeMeal(() => {
            this.getOrderDetail(body => {
            });
        })
    }
    // 蛋糕机制作完成
    cakeCompletion(arr) {
        let content;
        this.tcpSend(this.machineType, content);
    }
    // 获取扫描二维码取单
    cakeTakeMeal() {
        // 判断二维码订单是否和取餐订单相同，判断取餐口是否相同
        this.cakeOpenWindow();
    }
    // 通知PLC打开出餐口
    cakeOpenWindow() {
        let content;
        this.tcpSend(this.machineType, content);
    }
    // PCL发送订单超时
    cakeOverTime() {
    }

}
module.exports = cake;